


package com.xnyzc.lhy.order.service.impl.task;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xnyzc.lhy.common.component.redis.RedisCommon;
import com.xnyzc.lhy.common.constant.RedisPrefixConstant;
import com.xnyzc.lhy.common.entity.DiDiRv;
import com.xnyzc.lhy.common.exception.DiDiException;
import com.xnyzc.lhy.common.penum.EDiDiErrorCode;
import com.xnyzc.lhy.common.penum.order.EDiDiOrderStatus;
import com.xnyzc.lhy.common.penum.order.EOrderStatus;
import com.xnyzc.lhy.common.util.CheckUtil;
import com.xnyzc.lhy.order.entity.common.order.OrderCommon;
import com.xnyzc.lhy.order.entity.order.OaCOrder;
import com.xnyzc.lhy.order.entity.order.OaCOrderPersonal;
import com.xnyzc.lhy.order.entity.order.OaDOrder;
import com.xnyzc.lhy.order.entity.param.order.OrderDetailParam;
import com.xnyzc.lhy.order.entity.task.CloseOrderParam;
import com.xnyzc.lhy.order.entity.task.OrderStatusResults;
import com.xnyzc.lhy.order.entity.task.pay.PayInfo;
import com.xnyzc.lhy.order.entity.task.pay.PayTrade;
import com.xnyzc.lhy.order.entity.user.OaDUserInfo;
import com.xnyzc.lhy.order.feign.didi.IDidiService;
import com.xnyzc.lhy.order.mapper.order.OaCOrderPersonalMapper;
import com.xnyzc.lhy.order.mapper.order.OaDOrderMapper;
import com.xnyzc.lhy.order.mapper.user.OaDUserInfoMapper;
import com.xnyzc.lhy.order.service.task.IDriverProtectionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 司机保护
 *
 * @author zhengxu
 */
@Slf4j
@Service
public class DriverProtectionServiceImpl implements IDriverProtectionService {
    @Autowired
    private OaDUserInfoMapper oaDUserInfoMapper;

    @Autowired
    private OaDOrderMapper oaDOrderMapper;

    @Autowired
    private RedisCommon redisCommon;

    @Autowired
    private IDidiService iDidiService;

    @Autowired
    private OaCOrderPersonalMapper oaCOrderPersonalMapper;

    @Autowired
    private OrderCommon orderCommon;

    @Override
    public void driverLockProtection() {
        log.info("司机防锁定：开始被调用！！");
        // 查找所有锁定司机
        QueryWrapper<OaDUserInfo> queryWrapper = new QueryWrapper<>();
        // 获取被锁定的司机
        queryWrapper.select(OaDUserInfo.DRIVER_ID, OaDUserInfo.IS_ORDER, OaDUserInfo.CURRENT_ORDER_NO);
        queryWrapper.eq(OaDUserInfo.IS_ORDER, 1);
        List<OaDUserInfo> oaDUserInfoList = oaDUserInfoMapper.selectList(queryWrapper);
        if (CheckUtil.collectionIsEmpty(oaDUserInfoList)) {
            return;
        }
        for (OaDUserInfo oaDUserInfo : oaDUserInfoList) {
            if (CheckUtil.objIsEmpty(oaDUserInfo)) {
                continue;
            }
            String orderNo = oaDUserInfo.getCurrentOrderNo();
            // 释放司机
            if (CheckUtil.strIsEmpty(orderNo)) {
                updateDriverLockStatus(oaDUserInfo.getDriverId(), "因为未获取到订单号释放司机", 0);
                continue;
            }
            OaCOrderPersonal oaCOrder = null;
            QueryWrapper<OaCOrderPersonal> queryWrapperOrder = new QueryWrapper<>();
            queryWrapperOrder.select(OaCOrderPersonal.ORDER_NO, OaCOrderPersonal.ORDER_STATUS, OaCOrderPersonal.DIDI_ORDER_ID);
            queryWrapperOrder.eq(OaCOrderPersonal.ORDER_NO, orderNo);
            List<OaCOrderPersonal> oaCOrderPersonals = oaCOrderPersonalMapper.selectList(queryWrapperOrder);
            if (CheckUtil.collectionIsEmpty(oaCOrderPersonals)) {
                continue;
            }
            oaCOrder = oaCOrderPersonals.get(0);
            //如果为空不需要进行检验,释放司机
            if (CheckUtil.objIsEmpty(oaCOrder)) {
                updateDriverLockStatus(oaDUserInfo.getDriverId(), orderNo, -1);
                continue;
            }
            //判断当前订单状态释放,因为释放司机
            EOrderStatus orderStatus = EOrderStatus.findById(oaCOrder.getOrderStatus());
            if (CheckUtil.objIsEmpty(orderStatus)) {
                updateDriverLockStatus(oaDUserInfo.getDriverId(), orderNo, oaCOrder.getOrderStatus());
                continue;
            }
            //判断当前状态是否应该释放司机
            boolean freedDriver = EOrderStatus.isFreedDriver(orderStatus);
            if (freedDriver) {
                //释放司机
                updateDriverLockStatus(oaDUserInfo.getDriverId(), orderNo, oaCOrder.getOrderStatus());
                continue;
            }
            // 如果状态为 0 则计数 +1，如果为count为 2 释放司机
            if (orderStatus == EOrderStatus.waitingResponse) {
                String redisKey = RedisPrefixConstant.DRIVER_IS_ERROR + orderNo + oaDUserInfo.getDriverId();
                if (!redisCommon.hashKey(redisKey)) {
                    redisCommon.set(redisKey, "1", 900);
                } else {
                    String str = redisCommon.getStr(redisKey);
                    log.info("司机防锁定：找到已存在异常信息的被锁定司机，司机ID为：{}，订单号为：{}, 此订单被计数：{}次", oaDUserInfo.getDriverId(), orderNo, str);
                    if (StringUtils.equals("1", str)) {
                        redisCommon.set(redisKey, "2", 900);
                    } else {
                        // 释放司机
                        log.info("司机防锁定：被锁定司机达成被释放条件，司机ID为：{}，订单号为：{}, 此订单被计数：{}次", oaDUserInfo.getDriverId(), orderNo, str);
                        // 查询滴滴订单状态
                        OrderDetailParam orderDetailParam = new OrderDetailParam();
                        orderDetailParam.setOrder_id(orderNo);
                        orderDetailParam.setOpen_oid(oaCOrder.getDidiOrderId());
                        try {
                            DiDiRv diDiRvStatus = iDidiService.getOrderStatus(orderDetailParam);
                            Object data = diDiRvStatus.getData();
                            String jsonStr = JSON.toJSONString(data);
                            OrderStatusResults orderStatusResults = JSONObject.parseObject(jsonStr, OrderStatusResults.class);
                            String status = orderStatusResults.getStatus();
                            EDiDiOrderStatus byDidiType = EDiDiOrderStatus.findByDidiType(Integer.valueOf(status));

                            UpdateWrapper<OaCOrderPersonal> updateWrapper = new UpdateWrapper<>();
                            updateWrapper.set(OaCOrderPersonal.ORDER_STATUS, byDidiType.getType());
                            updateWrapper.set(OaCOrderPersonal.DIDI_ORDER_STATUS, byDidiType.getDidiType());
                            updateWrapper.eq(OaCOrderPersonal.ORDER_NO, orderNo);
                            int update = oaCOrderPersonalMapper.update(null, updateWrapper);
                            log.info("司机防锁定：查询订单状态成功！司机ID为：{}，订单号为：{}，更改订单状态：{}, 修改的订单状态为：{}", oaDUserInfo.getDriverId(), orderNo, update>0?"成功":"失败", status);
                        } catch (Exception e) {
                            log.error("司机防锁定：查询订单状态失败，司机ID为：{}，订单号为：{}", oaDUserInfo.getDriverId(), orderNo);
                        }
                        updateDriverLockStatus(oaDUserInfo.getDriverId(), orderNo, orderStatus.getType());
                        redisCommon.remove(redisKey);
                        redisCommon.remove(RedisPrefixConstant.ORDER_OA_D_ORDER + orderNo);
                    }
                }
            }
        }
    }

    /**
     * 更改司机锁定状态
     */
    public void updateDriverLockStatus(Long driverId, String orderNo, Integer orderStatus) {
        UpdateWrapper<OaDUserInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set(OaDUserInfo.IS_ORDER, 0);
        updateWrapper.set(OaDUserInfo.CURRENT_ORDER_NO, "");
        updateWrapper.eq(OaDUserInfo.DRIVER_ID, driverId);
        int update = oaDUserInfoMapper.update(null, updateWrapper);
        if (update < 1) {
            // 记录日志
            log.info("DRIVER_HISTORY 司机被释放了失败,司机当前订单号:[{}],当前订单状态:[{}],司机ID:[{}]", orderNo, orderStatus, driverId);
            return;
        }
        log.info("DRIVER_HISTORY 司机被释放了,司机当前订单号:[{}],当前订单状态:[{}],司机ID:[{}]", orderNo, orderStatus, driverId);
    }

    /**
     * 查看未支付订单-oa_d_order（每天晚上11点触发）
     */
    @Override
    public void paymentReview() {
        // 查找司机接单表所有待支付订单
        List<OaDOrder> oaDOrderList = oaCOrderPersonalMapper.getOrderMessage(EDiDiOrderStatus.normalOrderPendingPayment.getType());
        if (CheckUtil.collectionIsEmpty(oaDOrderList)) {
            return;
        }
        for (OaDOrder order : oaDOrderList) {
            // 调用查询订单详情
            OrderDetailParam orderDetailParam = new OrderDetailParam();
            orderDetailParam.setOrder_id(order.getOrderNo());
            orderDetailParam.setOpen_oid(order.getDidiOrderId());
            DiDiRv orderStatus = iDidiService.getOrderStatus(orderDetailParam);
            try {
                Object data = orderStatus.getData();
                String jsonStr = JSON.toJSONString(data);
                OrderStatusResults orderStatusResults = JSONObject.parseObject(jsonStr, OrderStatusResults.class);
                String status = orderStatusResults.getStatus();
                // 如果订单已支付,修改订单状态
                if (StringUtils.equals(status, EDiDiOrderStatus.paymented.getDidiType().toString())) {
                    Date date = new Date();
                    // 修改OaDOrder表
                    UpdateWrapper<OaDOrder> updateOrder = new UpdateWrapper<>();
                    updateOrder.set(OaDOrder.ORDER_STATUS, EDiDiOrderStatus.paymented.getType());
                    updateOrder.set(OaDOrder.UPDATE_TIME, date);
                    updateOrder.set(OaDOrder.VERSION, order.getVersion() + 1);
                    updateOrder.eq(OaDOrder.VERSION, order.getVersion());
                    updateOrder.eq(OaDOrder.ORDER_NO, order.getOrderNo());
                    int update = oaDOrderMapper.update(null, updateOrder);
                    if (update < 1) {
                        log.error("更新OaDOrder表失败");
                    }
                    // 查询支付详情设置用户支付金额
                    CloseOrderParam closeOrderParam = new CloseOrderParam();
                    closeOrderParam.setOrder_id(order.getOrderNo());
                    closeOrderParam.setOpen_oid(order.getDidiOrderId());
                    PayInfo payInfo = iDidiService.getPayInfo(closeOrderParam);
                    List<PayTrade> payTradeList = payInfo.getPay_trade_list();
                    Integer actualFee = 0;
                    if (CheckUtil.collectionIsEmpty(payTradeList)) {
                        throw DiDiException.create(EDiDiErrorCode.didiRequestPaymentNoticeNotInfo);
                    }
                    for (PayTrade payTrade : payTradeList) {
                        actualFee += payTrade.getCost();
                    }
                    BigDecimal bigDecimal = new BigDecimal(actualFee.toString());
                    bigDecimal = bigDecimal.divide(new BigDecimal("100"));
                    // 修改OaCOrderPersonal表
                    UpdateWrapper<OaCOrderPersonal> updateOrderPersonal = new UpdateWrapper<>();
                    updateOrderPersonal.set(OaCOrderPersonal.ORDER_STATUS, EDiDiOrderStatus.paymented.getType());
                    updateOrderPersonal.set(OaCOrderPersonal.DIDI_ORDER_STATUS, status);
                    updateOrderPersonal.set(OaCOrderPersonal.ACTUAL_FEE, bigDecimal);
                    updateOrderPersonal.set(OaCOrderPersonal.UPDATE_TIME, date);
                    updateOrderPersonal.set(OaCOrderPersonal.VERSION, order.getVersionOrderPersonal() + 1);
                    updateOrderPersonal.eq(OaCOrderPersonal.VERSION, order.getVersionOrderPersonal());
                    updateOrderPersonal.eq(OaCOrderPersonal.ORDER_NO, order.getOrderNo());
                    int updatePersonal = oaCOrderPersonalMapper.update(null, updateOrderPersonal);
                    if (updatePersonal < 1) {
                        log.error("更新OaCOrderPersonal表失败");
                    }
                }
            } catch (Exception e) {
                log.error(e.getMessage());
                log.error("查看未支付订单失败");
                continue;
            }
        }
    }
}
